#ifndef ROOTFINDERENVIRONMENT_H_
#define ROOTFINDERENVIRONMENT_H_

#include <string>

#include "Term.h"
#include "../Environment.h"
#include "../../Solution/ValueEncoded/ValueEncodedSolution.h"
#include "../../Crossover/SinglePoint/SinglePointCrossover.h"
#include "../../Crossover/RandomGeneration/RandomGenerationCrossover.h"
#include "../../Exception/GA_Exception.h"

/** Environment for finding the root of a multivariable polynomial.
 */
template <typename T=ValueEncodedSolution<int> >
class RootFinderEnvironment : public Environment
{
    public:
        RootFinderEnvironment();
        Crossover* configureCrossover();                         /**< Returns a crossover that will work with this environment    */
        void configure();                                        /**< Configures the environment                                  */
        void configure(string s) { };                            /**< Configures the environment from a file                      */
        double evaluateFitness(Solution*);                       /**< Evaluates the fitness of the given solution                 */
        void generateRandomPopulation(vector<Solution*> &, unsigned int); /**< Filess the provided vector with a random population         */
        string formatSolution(Solution*);                        /**< Outputs the solution with extra information                 */
        virtual ~RootFinderEnvironment() { };
        
        static Environment* getEnvironment();                    /**< RootFinder Environment factory function                     */
        
    private:
        double evaluateTerms(Solution*);
        // TODO: Add a second template parameter to allow for float terms?
        vector<Term<int> > terms;
        int variableCount;
        
};

#endif /*ROOTFINDERENVIRONMENT_H_*/
